/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

package xowl.interpreter;

/**
 *
 * @author Laurent WOUTERS
 */
public class LibManager {
    static final String comp = "LibManager";
    
    private xowl.utils.logging.Logger logger;
    private String libsPath;
    private java.util.List<String> loaded;
    private java.lang.reflect.Method addURL;
    
    public LibManager(xowl.utils.logging.Logger logger, String path) {
        this.logger = logger;
        this.loaded = new java.util.LinkedList<String>();
        try { this.addURL = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new java.lang.Class[]{java.net.URL.class}); }
        catch (NoSuchMethodException ex) { }
        catch (SecurityException ex) { }
        this.addURL.setAccessible(true);
        this.libsPath = path;
        if (!libsPath.endsWith(java.io.File.separator))
            this.libsPath = this.libsPath + java.io.File.separator;
    }
    
    public boolean execute(String[] batch) {
        for (int i=0; i!=batch.length; i++)
            load(batch[i]);
        return true;
    }

    public boolean load(String name) {
        if (loaded.contains(name))
            return true;
        boolean sucess = loadFile(name);
        if (sucess)
            loaded.add(name);
        return sucess;
    }

    private java.net.URL getURL(String file) throws java.net.MalformedURLException {
        java.io.File f = new java.io.File(libsPath + file);
        if (!f.exists())
            return null;
        return f.toURI().toURL();
    }

    private boolean loadFile(String file) {
        java.net.URL url = null;
        try {
            url = getURL(file);
            if (url == null) {
                logger.fatal(comp, "File " + file + " does not exist!");
                return false;
            }
        }
        catch (java.net.MalformedURLException ex) {
            logger.fatal(comp, "Cannot find file " + file);
            return false;
        }
        return loadJar(url);
    }
    private boolean loadJar(java.net.URL url) {
        try { addURL.invoke(java.lang.ClassLoader.getSystemClassLoader(), url); }
        catch (IllegalAccessException ex) {
            loadJarOnError(url);
            return false;
        }
        catch (IllegalArgumentException ex) {
            loadJarOnError(url);
            return false;
        }
        catch (java.lang.reflect.InvocationTargetException ex) {
            loadJarOnError(url);
            return false;
        }
        logger.debug(comp, "Dynamically loaded " + url.toString());
        return true;
    }
    
    private void loadJarOnError(java.net.URL url) {
        logger.fatal(comp, "Cannot load library " + url.toString());
    }
}
